package com.itheima.leetcode.od.c.string;

import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;

/**
 * <h3>IPv4地址转换成整数</h3>
 */
public class ConvertIPv4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();


        String[] ip4Addr = input.split("#");

        // 直接检查split后数组的长度是否为4即可
        if (ip4Addr.length != 4) {
            System.out.println("invalid IP");
            return;
        }

        // 创建一个列表来存储解析出的数字
        List<Integer> nums = new ArrayList<>();

        // 调用valid函数进行详细验证
        if (!valid(ip4Addr, nums)) {
            System.out.println("invalid IP");
        } else {
            // 如果验证通过，则转换并打印结果
            System.out.println(toNum(nums));
        }

        scanner.close();
    }

    /**
     * 验证IP地址的各个段是否符合规则
     *
     * @param ip4Addr 分割后的IP地址字符串数组
     * @param nums    用于存储转换后整数的列表 (输出参数)
     * @return 如果所有段都有效，则返回true，否则返回false
     */
    private static boolean valid(String[] ip4Addr, List<Integer> nums) {
        // C代码在这里也检查了size，但在Java中，我们在main函数里检查一次更清晰
        // if (ip4Addr.length != 4) { return false; }

        for (int i = 0; i < ip4Addr.length; i++) {
            String str = ip4Addr[i];
            int len = str.length();

            // 检查段长度是否为1到3位
            if (len == 0 || len > 3) {
                return false;
            }

            // 检查是否有前导零，例如 "01", "00"
            if (len > 1 && str.charAt(0) == '0') {
                return false;
            }

            // 检查字符串是否只包含数字
            for (int j = 0; j < len; j++) {
                if (!Character.isDigit(str.charAt(j))) {
                    return false;
                }
            }

            int num;
            // 尝试将字符串转换为数字
            try {
                num = Integer.parseInt(str);
            } catch (NumberFormatException e) {
                // 如果格式错误 (虽然前面的isDigit检查已经覆盖了这种情况)
                return false;
            }

            // 检查数值范围
            if (i == 0) {
                // 第一段范围: [1, 128]
                if (num < 1 || num > 128) {
                    return false;
                }
            } else {
                // 其余段范围: [0, 255]
                if (num < 0 || num > 255) {
                    return false;
                }
            }

            // 如果所有检查都通过，将数字添加到列表中
            nums.add(num);
        }
        return true;
    }

    /**
     * 将包含4个整数的列表通过位运算转换为一个long类型的32位整数
     *
     * @param ip4Arr 存储IP各段整数的列表
     * @return 转换后的长整型数值
     */
    private static long toNum(List<Integer> ip4Arr) {
        long ans = 0;
        // 注意：需要将整数先转换为long再进行位移，以防止符号扩展问题
        ans |= (long) ip4Arr.get(0) << 24;
        ans |= (long) ip4Arr.get(1) << 16;
        ans |= (long) ip4Arr.get(2) << 8;
        ans |= (long) ip4Arr.get(3);
        return ans;
    }
}